package com.snif.web.attach.core;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;

import com.snif.web.attach.core.config.JsonConfigReader;
import com.snif.web.attach.core.config.MethodConfig;
import com.snif.web.attach.core.service.MethodInvokeService;
import com.snif.web.attach.core.utils.ClassTik;
import com.snif.web.attach.core.utils.FormParamUtils;
import com.snif.web.attach.core.utils.LogUtils;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class RequestHandler implements HttpHandler {

	private final JsonConfigReader configReader;

	private final MethodInvokeService invokeService;



	public RequestHandler() {
		this.configReader = new JsonConfigReader();
		this.invokeService = new MethodInvokeService();

	}

	@Override
	public void handle(HttpExchange exchange) throws IOException {
		Map<String, Object> response = new HashMap<>();
		int statusCode = 200;

		try {
			// 从URL中解析methodId（GET和POST都从这里获取）
			URI uri = exchange.getRequestURI();
			String requestMethod = exchange.getRequestMethod();
			Map<String, String> queryParams = parseQueryParams(uri);
			String methodId = queryParams.get("methodId");

			// 验证methodId
			if (methodId == null || methodId.trim().isEmpty()) {
				throw new IllegalArgumentException("methodId参数不能为空");
			}

			// 根据methodId获取配置
			MethodConfig config = configReader.getConfig(methodId, requestMethod);
			LogUtils.info("寻址方法,id:{},方式:{},是否存在:{}", methodId, requestMethod, config != null);
			if (config == null) {
				throw new IllegalArgumentException("未找到ID为" + methodId + "的方法配置");
			}

			// 获取请求方法并验证
			// if (!requestMethod.equalsIgnoreCase(config.getMethod())) {
			// throw new IllegalArgumentException(
			// "请求方法不匹配，期望: " + config.getMethod() + ", 实际: " + requestMethod);
			// }

			// 解析参数（根据请求方法不同处理方式不同）
			List<MethodConfig.ParamMeta> paramMetas = config.getParams();
			Object[] params = new Object[0];
			if ("GET".equalsIgnoreCase(requestMethod)) {
				// GET请求从URL参数获取params
				params = buildParamObj(paramMetas, queryParams);
			}
			else if ("POST".equalsIgnoreCase(requestMethod)) {
				String contentType = exchange.getRequestHeaders().getFirst("Content-Type");
				if (contentType == null || !contentType.contains(config.getContentType())) {
					throw new RuntimeException("Content-Type不匹配,期望:" + config.getContentType() + ",实际:" + contentType);
				}
				// POST请求从JSON请求体获取params
				InputStream is = exchange.getRequestBody();
				String requestBody = FormParamUtils.readInputStreamAsString(is);
				if ("application/json".equals(config.getContentType())) {
					if ("{}".equals(requestBody)) {
						requestBody = null;
					}
					// if ("{}".equals(requestBody)) {
					// params = new Object[1];
					// }
					// else {
					// params = new Object[] { requestBody };
					// }
					params = new Object[] { requestBody };

				}
				else {
					Map<String, String> paramMap = FormParamUtils.parseFormBody(requestBody);
					params = buildParamObj(paramMetas, paramMap);
				}

			}

			// 调用目标方法（增加重试机制）
			Object result = invokeService.invokeMethod(config, params);

			// 构建成功响应
			response.put("success", true);
			response.put("result", result);

		}
		catch (Exception e) {
			// 处理异常
			statusCode = 400;
			response.put("success", false);
			String errorMsg;
			if (e instanceof InvocationTargetException) {
				errorMsg = e.getCause().getMessage();
			}
			else if (e instanceof NullPointerException) {
				errorMsg = "空指针异常";
			}
			else {
				errorMsg = e.getMessage();
			}
			response.put("error", errorMsg);
		}
		finally {
			// 发送响应
			String jsonResponse = JSONUtil.toJsonStr(response);
			exchange.sendResponseHeaders(statusCode, jsonResponse.getBytes(StandardCharsets.UTF_8).length);
			try (OutputStream os = exchange.getResponseBody()) {
				os.write(jsonResponse.getBytes(StandardCharsets.UTF_8));
			}
		}
	}



	private static Object[] buildParamObj(List<MethodConfig.ParamMeta> paramMetas, Map<String, String> dataParam) {
		Object[] params = new Object[0];
		if (CollectionUtil.isNotEmpty(paramMetas)) {
			List<Object> eles = new ArrayList<>();
			for (MethodConfig.ParamMeta paramMeta : paramMetas) {
				String paramName = paramMeta.getParamName();
				String paramType = paramMeta.getParamType();
				Class<?> typeClass = ClassTik.getTypeClass(paramType);
				String paramVal = dataParam.get(paramName);
				eles.add(Convert.convert(typeClass, paramVal));
			}
			params = eles.toArray(new Object[0]);
		}
		return params;
	}

	// 解析URL查询参数
	private Map<String, String> parseQueryParams(URI uri) {
		Map<String, String> params = new HashMap<>();
		String query = uri.getQuery();
		if (query != null && !query.isEmpty()) {
			String[] pairs = query.split("&");
			for (String pair : pairs) {
				String[] keyValue = pair.split("=", 2);
				if (keyValue.length == 2) {
					params.put(keyValue[0], keyValue[1]);
				}
				else if (keyValue.length == 1) {
					params.put(keyValue[0], "");
				}
			}
		}
		return params;
	}

}
